<?php
/**
 *+------------------
 * Lflow
 *+------------------
 * Copyright (c) 2023~2030 gitee.com/liu_guan_qing All rights reserved.本版权不可删除，侵权必究
 *+------------------
 * Author: Mr.April(405784684@qq.com)
 *+------------------
 */
declare (strict_types=1);

namespace lflow\model;

use lflow\DecisionHandler;
use lflow\Expression;
use lflow\helper\StringHelper;
use lflow\implement\JuelExpression;
use lflow\Logger;
use lflow\workflow\Execution;
use lflow\WorkFlowException;

/**
 * 决策定义Decision元素
 *
 * @author Mr.April
 * @since  1.0
 */
class DecisionModel extends NodeModel
{

    /**
     * 决策选择表达式串（需要表达式引擎解析）
     */
    private string $expr;

    /**
     * 决策处理类，对于复杂的分支条件，可通过handleClass来处理
     */
    private string $handleClass;

    /**
     * 决策处理类实例
     */
    private DecisionHandler $decide;

    /**
     * 表达式解析器
     */
    private Expression $expression;

    /**
     * @param \lflow\workflow\Execution $execution
     *
     * @throws \lflow\WorkFlowException
     */
    public function exec(Execution $execution): void
    {
        $args = $execution->getOrder()->getVariable();
        Logger::info($execution->getOrder()->getId() . "->decision execution.getArgs():" . json_encode($execution->getArgs()));
        $Expression = new JuelExpression();
        Logger::info("expression is " . json_encode($Expression));
        //决策表达式
        if (StringHelper::isNotEmpty($this->expr)) {
            $next = null;
        } else {
            $next = null;
        }
        $isFound = false;
        Logger:: info($execution->getOrder()->getId() . "->decision expression[expr=" . $this->expr . "] return result:" . $next);
        foreach ($this->getOutputs() as $tm) {
            if (StringHelper::isEmpty($next)) {
                //无决策点expr 使用变迁
                $expr = $tm->getExpr();
                if (StringHelper::isNotEmpty($expr) && $Expression->eval($expr, $args)) {
                    $tm->setEnabled(true);
                    $tm->execute($execution);
                    $isFound = true;
                }
            } else {
                if (StringHelper::equalsIgnoreCase($tm->getName(), $next)) {
                    $tm->setEnabled(true);
                    $tm->execute($execution);
                    $isFound = true;
                }
            }
        }
        if (!$isFound) throw new WorkFlowException($execution->getOrder()->getId() . "->decision节点无法确定下一步执行路线");
    }

    public function getExpr(): string
    {
        return $this->expr;
    }

    public function setExpr(string $expr): void
    {
        $this->expr = $expr;
    }

    public function getHandleClass(): string
    {
        return $this->handleClass;
    }

    public function setHandleClass(string $handleClass): void
    {
        $this->handleClass = $handleClass;
    }

}
